﻿// Developer Express Code Central Example:
// World Wide CRM Demo
// 
// The World Wide CRM demo is a next generation application with outstanding
// navigation capabilities and shows a reimagined view of customer contact and
// management. This demo showcases many of the most popular features of the
// WinForms Subscription.
// 
// You can find sample updates and versions for different programming languages here:
// http://www.devexpress.com/example=E3993

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraCharts;
using DevExpress.CrmDemo.Win.Data;
using DevExpress.CrmDemo.Win.Helpers;
using System.Diagnostics;
using DevExpress.XtraScheduler.UI;

namespace DevExpress.CrmDemo.Win.Controls {
    public partial class Dashboard : BasePage {
        public Dashboard() {
            InitializeComponent();
            this.header.BackRequest += new EventHandler(header_BackRequest);
        }

        public BindingList<Opportunity> Opportunities {
            set {
                this.opportunitiesByStage.Opportunities = value;
            }
        }

        private CompanyStatList companyStats = new CompanyStatList();

        public CompanyStatList CompanyStats {
            get { return companyStats; }
            set { companyStats = value; }
        }

        private CategoryStatList categoryStats = new CategoryStatList();

        public CategoryStatList CategoryStats {
            get { return categoryStats; }
            set { categoryStats = value; }
        }

        private TeamMemberStatDetailList teamMemberStatDetails = new TeamMemberStatDetailList();

        public TeamMemberStatDetailList TeamMemberStatDetails {
            get { return teamMemberStatDetails; }
            set { teamMemberStatDetails = value; }
        }

        private TeamMemberStatList teamMemberStats = new TeamMemberStatList();

        public TeamMemberStatList TeamMemberStats {
            get { return teamMemberStats; }
            set { teamMemberStats = value; }
        }


        void header_BackRequest(object sender, EventArgs e) {
            OnNavRequest(new NavRequestEventArgs(States.StartPage));
        }

        private void opportunitiesByStage_NavRequest(object sender, NavRequestEventArgs args) {
            OnNavRequest(args);
        }

        private void chartMarketingRevenue_CustomDrawSeriesPoint(object sender, DevExpress.XtraCharts.CustomDrawSeriesPointEventArgs e) {
            var chart = sender as ChartControl;

            bool isFirstSeries = chart.Series.IndexOf(e.Series) == 0;

            if (isFirstSeries) {
                int pointIndex = e.Series.Points.IndexOf(e.SeriesPoint);

                double firstSeriesValue = e.SeriesPoint.Values[1];
                double secondSeriesValue = chart.Series[1].Points[pointIndex].Values[1];

                if (firstSeriesValue >= secondSeriesValue) {
                    e.SeriesDrawOptions.Color = Color.FromArgb(255, 65, 126, 17);
                } else {
                    e.SeriesDrawOptions.Color = Color.FromArgb(255, 151, 8, 14);
                }

                if (e.SeriesDrawOptions is BarDrawOptions) {
                    ((BarDrawOptions)e.SeriesDrawOptions).FillStyle.FillMode = FillMode.Solid;
                }
            }
        }

        private void monthSlider_ValueChanged(object sender, EventArgs e) {
            RefreshStats();
        }

        private void Dashboard_Load(object sender, EventArgs e) {
            companyStatsBindingSource.DataSource = CompanyStats;
            categoryStatBindingSource.DataSource = CategoryStats;
            newOppsListBindingSource.DataSource = DataProvider.Instance.NewestOpportunities;
            newApptsListBindingSource.DataSource = DataProvider.Instance.NewestAppointments;
            generalStatsBindingSource.DataSource = DataProvider.Instance.GeneralStats;
            generalStatsBindingSource.CurrentItemChanged += new EventHandler(generalStatsBindingSource_CurrentItemChanged);
            RefreshGeneralStats((GeneralStats)generalStatsBindingSource.DataSource);

            teamMember1.StatDetailDataSource = TeamMemberStatDetails;
            teamMember1.StatDataSource = TeamMemberStats;
            teamMember2.StatDetailDataSource = TeamMemberStatDetails;
            teamMember2.StatDataSource = TeamMemberStats;
            teamMember3.StatDetailDataSource = TeamMemberStatDetails;
            teamMember3.StatDataSource = TeamMemberStats;
            teamMember4.StatDetailDataSource = TeamMemberStatDetails;
            teamMember4.StatDataSource = TeamMemberStats;

            keywordStatBindingSource.DataSource = DataProvider.Instance.KeywordStats;

            RefreshStats();

            timer = new Timer();
            timer.Tick += new EventHandler(timer_Tick);
            timer.Interval = 5000;
            timer.Start();
        }

        void timer_Tick(object sender, EventArgs e) {
            try {
                RefreshNewOppTile();
                DataProvider.Instance.RefreshNewAppointmentsList();
            } catch { }
        }

        Timer timer;

        void generalStatsBindingSource_CurrentItemChanged(object sender, EventArgs e) {
            RefreshGeneralStats((GeneralStats)generalStatsBindingSource.DataSource);
        }

        void RefreshGeneralStats(GeneralStats stats) {
            if (stats == null)
                return;

            lblClosingPercentage.Text = (stats.YtdPercentClosing * 100).ToString("F0") + "%"; // not using "P0" here to avoid the space between # and %
            lblClosingText.Text = "of new opportunities are closing in " + DateTime.Now.Year;
        }

        void RefreshStats() {
            DateTime startDate = monthSlider.SelectionStartDate;
            DateTime endDate = monthSlider.SelectionEndDate;

            lblDateRange.Text = startDate.ToString("MMMM d yyyy") + " - " + endDate.AddDays(-1).ToString("MMMM d yyyy");

            DataProvider.RefreshCompanyStats(startDate, endDate, CompanyStats);
            DataProvider.RefreshCategoryStats(startDate, endDate, CategoryStats);

            List<TeamMemberControl> teamMembers = new List<TeamMemberControl>() { teamMember1, teamMember2, teamMember3, teamMember4 };

            DataProvider.RefreshTeamStats(startDate, endDate, TeamMemberStats, TeamMemberStatDetails);
        }

        private void pictureBoxReport_Click(object sender, EventArgs e) {
            OnNavRequest(new NavRequestEventArgs(States.ReportViewer));
        }

        private void newOppsListBindingSource_ListChanged(object sender, ListChangedEventArgs e) {
            RefreshNewOppTile();
        }

        private void RefreshNewOppTile() {
            BindingList<Opportunity> newOpps = (BindingList<Opportunity>)newOppsListBindingSource.DataSource;

            for (int i = 0; i < newOpps.Count(); i++) {
                ApplyOppDataToTileItemInfo(newOpps[i], tileItem.Frames[i]);
            }
        }

        void ApplyOppDataToTileItemInfo(Opportunity opp, TileItemFrame tileItemInfo) {
            int mainTextMaxLength = 60;

            string mainText = opp.AccountName + " - " + opp.Name;

            if (mainText != null && mainText.Length > mainTextMaxLength)
                mainText = mainText.Substring(0, mainTextMaxLength - 3) + "...";

            int subTextMaxLength = 80;

            string subText = opp.NextStep;

            if (subText != null && subText.Length > subTextMaxLength)
                subText = subText.Substring(0, subTextMaxLength - 3) + "...";

            string content = "";
            content += "<size=12>" + mainText + "</size>" + Environment.NewLine;
            content += "<size=4><b> </b></size>\n"; // spacer
            content += "<size=9><color=210,210,210>" + (opp.CostSize ?? 0).ToString("C0").PadRight(32) + (opp.Technology ?? "").PadLeft(32) + "</color></size>\n";
            content += "<size=4><b> </b></size>\n"; // spacer
            content += string.Format("<size=9>" + subText + "</size>");

            tileItemInfo.Text = content;

            tileItemInfo.Text4 = string.Format("<size=8><color=210,210,210>{0}</color></size>", opp.AgeText);
            tileItemInfo.Tag = opp.ID;
        }

        private void tileItem_ItemClick(object sender, TileItemEventArgs e) {
            object tag = tileItem.CurrentFrame.Tag;

            if (tag != null) {
                OnNavRequest(new NavRequestEventArgs(States.OppDetail, (int)tag));
            }
        }

        private void newOpp_Click(object sender, EventArgs e) {
            Opportunity newOpp = DataProvider.Instance.CreateNewOpportunity();

            OnNavRequest(new NavRequestEventArgs(States.OppDetail, newOpp.ID));
        }

        private void scheduler_Click(object sender, EventArgs e) {
            OnNavRequest(new NavRequestEventArgs(States.Scheduler));
        }

        private void newApptsListBindingSource_ListChanged(object sender, ListChangedEventArgs e) {
            RefreshNewApptsTile();
        }

        private void RefreshNewApptsTile() {
            BindingList<CustomAppointment> newAppts = (BindingList<CustomAppointment>)newApptsListBindingSource.DataSource;

            for (int i = 0; i < newAppts.Count(); i++) {
                ApplyApptDataToTileItemInfo(newAppts[i], tileItem2.Frames[i]);
            }
        }

        void ApplyApptDataToTileItemInfo(CustomAppointment appt, TileItemFrame tileItemInfo) {
            int mainTextMaxLength = 60;

            string mainText = appt.Subject;

            if (mainText != null && mainText.Length > mainTextMaxLength)
                mainText = mainText.Substring(0, mainTextMaxLength - 3) + "...";

            int subTextMaxLength = 80;

            string subText = appt.Description;

            if (subText != null && subText.Length > subTextMaxLength)
                subText = subText.Substring(0, subTextMaxLength - 3) + "...";

            string content = "";
            content += "<size=12>" + mainText + "</size>" + Environment.NewLine;
            content += "<size=4><b> </b></size>\n"; // spacer
            content += string.Format("<size=9>" + subText + "</size>");

            tileItemInfo.Text = content;

            tileItemInfo.Text4 = string.Format("<size=8><color=210,210,210>{0}</color></size>", appt.StartTime.ToString("MMMM d, yyyy H:mm tt"));
        }

        private void tileItem2_ItemClick(object sender, TileItemEventArgs e) {
            OnNavRequest(new NavRequestEventArgs(States.Scheduler));
        }

        private void chartCompanyNumber_ObjectHotTracked(object sender, HotTrackEventArgs e) {
            SeriesPoint point = e.AdditionalObject as SeriesPoint;

            if (point != null) {
                CompanyStat stat = (CompanyStat)point.Tag;

                string hoverText = stat.Count.ToString() + " " + (stat.Count == 1 ? "Opportunity" : "Opportunities") + " in " + stat.Date.ToString("MMMM yyyy");

                toolTipController1.ShowHint(hoverText);
            } else {
                toolTipController1.HideHint();
            }
        }

        private void chartCategoryNumber_ObjectHotTracked(object sender, HotTrackEventArgs e) {
            SeriesPoint point = e.AdditionalObject as SeriesPoint;

            if (point != null) {
                CategoryStat stat = (CategoryStat)point.Tag;

                string hoverText = stat.Count.ToString() + " " + stat.Tech + " " + (stat.Count == 1 ? "Opportunity" : "Opportunities");

                toolTipController1.ShowHint(hoverText);
            } else {
                toolTipController1.HideHint();
            }
        }

        private void chartCategoryValue_ObjectHotTracked(object sender, HotTrackEventArgs e) {
            SeriesPoint point = e.AdditionalObject as SeriesPoint;

            if (point != null) {
                CategoryStat stat = (CategoryStat)point.Tag;

                string hoverText = (stat.Amount * 1000).ToString("C0");

                toolTipController1.ShowHint(hoverText);
            } else {
                toolTipController1.HideHint();
            }
        }

        private void chartMarketingRevenue_ObjectHotTracked(object sender, HotTrackEventArgs e) {
            SeriesPoint point = e.AdditionalObject as SeriesPoint;

            if (point != null) {
                int pointIndex = point.SeriesPointID;

                int actual = (int)chartMarketingRevenue.Series[0].Points[pointIndex].Values[1];
                int target = (int)chartMarketingRevenue.Series[1].Points[pointIndex].Values[1];

                string hoverText =
                    "Target: " + (target * 1000).ToString("C0") + Environment.NewLine +
                    "Actual: " + (actual * 1000).ToString("C0") + Environment.NewLine +
                    "Difference: " + ((actual - target) * 1000).ToString("C0");

                toolTipController1.ShowHint(hoverText);
            } else {
                toolTipController1.HideHint();
            }
        }

        private void gridView1_CustomDrawColumnHeader(object sender, XtraGrid.Views.Grid.ColumnHeaderCustomDrawEventArgs e) {
            if (e.Column != null) 
                e.Appearance.DrawString(e.Cache, e.Column.GetCaption(), e.Info.CaptionRect);
            e.Handled = true;
        }
    }
}